package com.x.provider.customer.service.common;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.x.core.domain.SuggestionTypeEnum;
import com.x.core.utils.ApiAssetUtil;
import com.x.core.utils.BeanUtil;
import com.x.core.utils.JsonUtil;
import com.x.core.web.api.R;
import com.x.core.web.api.ResultCode;
import com.x.provider.api.oss.enums.ContentGroupTypeEnum;
import com.x.provider.api.oss.enums.MimeTypeEnum;
import com.x.provider.api.oss.model.dto.green.AddGreenNotifyRequestDTO;
import com.x.provider.api.oss.model.dto.green.GreenRequestDTO;
import com.x.provider.api.oss.service.GreenRpcService;
import com.x.provider.customer.constant.CustomerConstants;
import com.x.provider.customer.enums.AttributeKeyGroupEnum;
import com.x.provider.customer.mapper.GenericAttributeMapper;
import com.x.provider.customer.model.ao.AddOrUpdateAttributeAO;
import com.x.provider.customer.model.domain.common.GenericAttribute;
import com.x.provider.customer.model.query.common.GenericAttributeQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

@Slf4j
@Service
public class GenericAttributeServiceImpl implements GenericAttributeService {

    private final RedisKeyService redisKeyService;
    private final GenericAttributeMapper genericAttributeMapper;
    private final GreenRpcService greenRpcService;

    public GenericAttributeServiceImpl(RedisKeyService redisKeyService,
                                       GenericAttributeMapper genericAttributeMapper,
                                       GreenRpcService greenRpcService){
        this.redisKeyService = redisKeyService;
        this.genericAttributeMapper = genericAttributeMapper;
        this.greenRpcService = greenRpcService;
    }

    @Override
    public List<GenericAttribute> listAttributeMap(String keyGroup, Long entityId) {
        throw new IllegalStateException("not supported");
    }

    @Override
    public GenericAttribute getAttribute(String keyGroup, Long entityId, String key) {
        throw new IllegalStateException("not supported");
    }

    @Override
    public GenericAttribute addOrUpdateAttribute(AddOrUpdateAttributeAO addOrUpdateAttributeAO) {
        GenericAttributeQuery genericAttributeQuery = GenericAttributeQuery.builder()
                .key(addOrUpdateAttributeAO.getKey())
                .keyGroup(addOrUpdateAttributeAO.getKeyGroup())
                .entityId(addOrUpdateAttributeAO.getEntityId())
                .suggestionType(addOrUpdateAttributeAO.getSuggestionType())
                .build();
        GenericAttribute genericAttribute = getBy(genericAttributeQuery);
        if (genericAttribute == null){
            genericAttribute = BeanUtil.prepare(addOrUpdateAttributeAO, GenericAttribute.class);
        }
        genericAttribute.setValue(addOrUpdateAttributeAO.getValue());
        genericAttribute.setSuggestionType(addOrUpdateAttributeAO.getSuggestionType());
        addOrUpdate(genericAttribute);
        return genericAttribute;
    }

    @Override
    public GenericAttribute addOrUpdateDraftAttribute(String keyGroup, Long entityId, String key, String value) {
        return addOrUpdateAttribute(AddOrUpdateAttributeAO.builder().key(key).keyGroup(keyGroup).value(value).entityId(entityId).suggestionType(SuggestionTypeEnum.NONE.getValue()).build());
    }

    @Override
    public void deleteDraftAttribute(String keyGroup, Long entityId, String key) {
        final GenericAttribute genericAttribute = getBy(GenericAttributeQuery.builder().keyGroup(keyGroup).key(key).entityId(entityId).suggestionType(SuggestionTypeEnum.NONE.getValue()).build());
        if (genericAttribute != null){
            genericAttributeMapper.deleteById(genericAttribute.getId());
        }
    }

    @Override
    public List<GenericAttribute> listAttributeMap(String keyGroup, List<Long> entityIdList) {
        return genericAttributeMapper.selectList(buildQuery(GenericAttributeQuery.builder().keyGroup(keyGroup).entityIdList(entityIdList).build()));
    }

    @Override
    public void setAttribute(String keyGroup, Long entityId, String key, String value, MimeTypeEnum greenType) {
        switch (greenType){
            case NULL:
                addOrUpdateAttribute(AddOrUpdateAttributeAO.builder()
                        .keyGroup(keyGroup)
                        .key(key)
                        .entityId(entityId)
                        .suggestionType(SuggestionTypeEnum.PASS.getValue())
                        .value(value)
                        .build());
            case TEXT:
            case PICTURE:
//                R<String> greenResult = greenRpcService.greenSync(GreenRequestDTO.builder().value(value).dataType(greenType.name()).build());
//                ApiAssetUtil.isTrue(greenResult.getData().equals(SuggestionTypeEnum.PASS.name()), ResultCode.GREEN_BLOCKED);
                addOrUpdateAttribute(AddOrUpdateAttributeAO.builder()
                        .keyGroup(keyGroup)
                        .key(key)
                        .entityId(entityId)
                        .suggestionType(SuggestionTypeEnum.PASS.getValue())
                        .value(value)
                        .build());
                break;
        }
    }

    @Override
    public void onDraftAttributeGreenFinished(GenericAttribute genericAttribute, SuggestionTypeEnum suggestionTypeEnum) {
        if (suggestionTypeEnum.equals(SuggestionTypeEnum.PASS)){
            addOrUpdateAttribute(AddOrUpdateAttributeAO.builder()
                    .keyGroup(AttributeKeyGroupEnum.CUSTOMER.name())
                    .entityId(genericAttribute.getEntityId())
                    .key(genericAttribute.getKey())
                    .value(genericAttribute.getValue())
                    .suggestionType(SuggestionTypeEnum.PASS.getValue())
                    .build());
        }
        deleteDraftAttribute(genericAttribute.getKeyGroup(), genericAttribute.getEntityId(), genericAttribute.getKey());
    }

    public void addOrUpdate(GenericAttribute genericAttribute){
        if (genericAttribute.getId() != null){
            genericAttributeMapper.updateById(genericAttribute);
            return;
        }
        genericAttributeMapper.insert(genericAttribute);
    }

    private Map<Long, Map<String, String>> prepare(List<GenericAttribute> source){
        if (source.isEmpty()){
            return new HashMap<>();
        }
        Map<Long, Map<String, String>> result = new HashMap<>();
        source.stream().forEach(item -> {
            if (!result.containsKey(item.getEntityId())){
                result.put(item.getEntityId(), new HashMap<>());
            }
            result.get(item.getEntityId()).put(item.getKey(), item.getValue());
        });
        return result;
    }

    private void save(String keyGroup, Long entityId, String key, String value){
        GenericAttribute genericAttribute = getBy(keyGroup, entityId, key);
        if (genericAttribute == null){
            genericAttribute = GenericAttribute.builder().entityId(entityId).key(key).keyGroup(keyGroup).value(value).build();
        }
        genericAttribute.setValue(value);
        if (genericAttribute.getId() > 0){
            genericAttributeMapper.updateById(genericAttribute);
        }
        else{
            genericAttributeMapper.insert(genericAttribute);
        }
    }

    private GenericAttribute getBy(String keyGroup, Long entityId, String key){
        return genericAttributeMapper.selectOne(buildQuery(GenericAttributeQuery.builder().keyGroup(keyGroup).entityId(entityId).key(key).build()));
    }

    private GenericAttribute getBy(GenericAttributeQuery genericAttributeQuery){
        return genericAttributeMapper.selectOne(buildQuery(genericAttributeQuery));
    }

    private LambdaQueryWrapper<GenericAttribute> buildQuery(GenericAttributeQuery genericAttributeQuery){
        LambdaQueryWrapper<GenericAttribute> result = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(genericAttributeQuery.getKeyGroup())){
            result.eq(GenericAttribute::getKeyGroup, genericAttributeQuery.getKeyGroup());
        }
        if (genericAttributeQuery.getEntityId() != null){
            result.eq(GenericAttribute::getEntityId, genericAttributeQuery.getEntityId());
        }
        if (!CollectionUtils.isEmpty(genericAttributeQuery.getEntityIdList())){
            result.in(GenericAttribute::getEntityId, genericAttributeQuery.getEntityIdList());
        }
        if (!StringUtils.isEmpty(genericAttributeQuery.getKey())){
            result.eq(GenericAttribute::getKey, genericAttributeQuery.getKey());
        }
        if (genericAttributeQuery.getSuggestionType() != null){
            result.eq(GenericAttribute::getSuggestionType, genericAttributeQuery.getSuggestionType());
        }
        return result;
    }

    private void setMediaAttribute(String keyGroup, Long entityId, String key, String value) {
        addOrUpdateDraftAttribute(keyGroup, entityId, key, value);
        try {

            greenRpcService.addGreenNotifyAsync(AddGreenNotifyRequestDTO.builder().notifyUrl(CustomerConstants.ATTRIBUTE_GREEN_CALLBACK_RUL)
                    .contentList(Arrays.asList(new AddGreenNotifyRequestDTO.ContentDTO(value, ContentGroupTypeEnum.OSS.getValue(), MimeTypeEnum.PICTURE.name())))
                    .extra(JsonUtil.toJSONString(GenericAttribute.builder().entityId(entityId).value(value).key(key).keyGroup(keyGroup).build()))
                    .build());
        }
        catch (Exception e){
            log.error(e.getMessage(), e);
            deleteDraftAttribute(keyGroup, entityId, key);
            throw e;
        }
    }

}
